#include "device/Memory.h"

Memory::Memory(size_t mem_size) : size(mem_size)
{
    this->data = new uint8_t[mem_size];
}

Memory::Memory(uint8_t* bin, size_t bin_size, size_t mem_size): size(mem_size)
{
    this->data = new uint8_t[mem_size];
    memcpy(this->data, bin, bin_size);
}

Memory::Memory(const char* filename, size_t mem_size) : size(mem_size)
{
    this->data = new uint8_t[mem_size];
    uint64_t file_size = std::filesystem::file_size(filename);
    assert(file_size <= mem_size);
    std::ifstream file(filename, std::ios::in | std::ios::binary);
    file.read((char*)data,file_size);
}

Memory::~Memory()
{
    delete[] data;
}

bool Memory::read(word_t start_addr, size_t length, uint8_t* buffer, bool& mmio) 
{
    word_t offset = start_addr - MEM_BASE;
    mmio = false;
    if (offset >= 0 && offset + length < size) {
        memcpy(buffer, data + offset, length);
        return true;
    }
    return false;
}

bool Memory::write(word_t start_addr, size_t length, const uint8_t* buffer, bool& mmio)
{
    word_t offset = start_addr - MEM_BASE;
    mmio = false;
    if (offset >= 0 && offset + length < size) {
        memcpy(data + offset, buffer, length);
        return true;
    }
    return false;
}

void Memory::update()
{
    return;
}

word_t Memory::get_size()
{
    return this->size;
}

uint8_t* Memory::get_base()
{
    return this->data;
}